package edu.cmu.cs211.exprtree.ast;

/**
 * Represents an operator that takes only one operand. For example, unary
 * negation, like -x.
 */
public abstract class UnaryExpression implements Expression {

	private final Expression operand;
	/**
	 * Creates a new unary expression
	 * 
	 * @param operand
	 *            The operand of the new expression.
	 * @throws NullPointerException
	 *             if operand is <code>null</code>
	 */
	public UnaryExpression (Expression operand) {
		if (operand == null)
			throw new NullPointerException();
		this.operand = operand;
	}

	/** An accessor for this node's operand */
	public final Expression getOperand ()
	{
		return operand;
	}

	/**
	 * Gets the symbol that represents this operation
	 * 
	 * @return the text symbol that represents this operator, for example '-'
	 *         for {@link NegationExpression}
	 */
	public abstract char getOperatorSymbol ();

	/**
	 * @return the string (op operand) with no space. For example, (-x)
	 */
	@Override
	public String toString ()
	{
		return String.format ("(%s%s)", getOperatorSymbol (), getOperand ());
	}

	@Override
	public boolean equals (Object obj)
	{
		if (this == obj)
			return true;
		if (obj == null)
			return false;

		if (!obj.getClass ().equals (getClass ()))
			return false;
		return ((UnaryExpression) obj).getOperand ().equals (getOperand ());
	}

	@Override
	public int hashCode ()
	{
		return getOperand ().hashCode () ^ getClass ().hashCode ();
	}
}
